<template>
  <div class="audio-player-warp" :style="{backgroundImage:'url('+curSong.image+')'}">
    <div class="audio-bg" />
    <div class="audio-header">
      {{ curSong.title }}-{{ curSong.author }}
    </div>
    <div class="audio-lyric-warp">
      <UiLyric :source-lyric="sourceLyric" :loading="searching" :cur-time="curTime" />
    </div>
    <div class="audio-player-control">
      <div class="audio-time-warp">
        <span class="duration-text">{{ duration | fmtTime }}</span>
        <span class="curTime-text">{{ curTime | fmtTime }}</span>
        <div class="audio-duration-warp">
          <UiProgress :preload="preload" :progress="played" @progress-change="updateTime" />
        </div>
      </div>
      <div class="player-control-warp">
        <span class="iconfont icon-prev" @click="prevSong" />
        <span class="iconfont toggle-play" :class="toggleClass" @click="togglePlay" />
        <span class="iconfont icon-next" @click="nextSong" />
        <span class="iconfont icon-menu" @click="toggleShow" />
      </div>
    </div>
    <div class="audio-list-warp" :class="{'list-hide':!isShow}">
      <p class="audio-list-header">播放列表({{ playList.length }})</p>
      <ul class="audio-list-container">
        <li v-for="(item,i) in playList" :key="i" @click="playSong(item)">{{ i+1 }}.{{ item.title }}-{{ item.author }}</li>
      </ul>
    </div>
  </div>
</template>

<script>
import UiProgress from '../../../components/UiProgress'
import UiLyric from '../../../components/UiLyric'
import Message from '../../../components/Message'
export default {
  name: 'MusicPlayer',
  components: {
    UiProgress,
    UiLyric
  },
  filters: {
    fmtTime(value) {
      let m = parseInt(value / 60)
      let s = parseInt(value % 60)
      if (m <= 9) {
        m = '0' + m
      }
      if (s <= 9) {
        s = '0' + s
      }
      return m + ':' + s
    }
  },
  data() {
    return {
      curSong: {},
      playList: [],
      duration: 0,
      curTime: 0,
      played: 0,
      preload: 0,
      volume: 0.5,
      isError: false,
      isPaused: true,
      sourceLyric: '',
      searching: false,
      isShow: false
    }
  },
  computed: {
    toggleClass() {
      if (this.isPaused) {
        return 'icon-play'
      }
      return 'icon-pause'
    }
  },
  mounted() {
    this.initPlayer()
    this.getPlayList('545888750')
  },
  methods: {
    togglePlay() {
      if (this.$audio.paused) {
        this.$audio.play()
      } else {
        this.$audio.pause()
      }
    },
    playSong(song) {
      this.changeSong(song)
      this.$audio.play()
    },
    changeSong(song) {
      if (song.id === this.curSong.id) {
        return
      }
      this.curTime = 0
      this.preload = 0
      this.duration = 0
      this.played = 0
      this.isError = false
      this.$audio.src = 'https://music.163.com/song/media/outer/url?id=' + song.id + '.mp3'
      this.curSong = song
      if ('mediaSession' in navigator) {
        navigator.mediaSession.metadata = new window.MediaMetadata({
          title: song.title,
          artist: song.author,
          album: song.title,
          artwork: [
            { src: song.image, sizes: '256x256', type: 'image/jpg' }
          ]
        })
      }
      this.getLyric(song.id)
    },
    prevSong() {
      const len = this.playList.length
      if (len <= 1) {
        return
      }
      const isPaused = this.$audio.paused
      const prevIndex = this.findIndex(this.curSong, this.playList) - 1
      let index = prevIndex
      if (prevIndex < 0) {
        index = len - 1
      }
      this.changeSong(this.playList[index])
      if (!isPaused) {
        this.$audio.play()
      }
    },
    nextSong() {
      const len = this.playList.length
      if (len <= 1) {
        return
      }
      const isPaused = this.$audio.paused
      const nextIndex = this.findIndex(this.curSong, this.playList) + 1
      let index = nextIndex
      if (nextIndex >= len) {
        index = 0
      }
      this.changeSong(this.playList[index])
      if (!isPaused) {
        this.$audio.play()
      }
    },
    findIndex(song, list) {
      const index = -1
      for (let i = 0; i < list.length; i++) {
        const item = list[i]
        if (item.id === song.id) {
          return i
        }
      }
      return index
    },
    initPlayer() {
      const _this = this
      const $audio = document.createElement('audio')
      this.$audio = $audio
      $audio.volume = this.volume
      $audio.onpause = () => {
        _this.isPaused = true
      }
      $audio.onplay = () => {
        _this.isPaused = false
      }
      $audio.ontimeupdate = function() {
        const time = $audio.currentTime
        _this.curTime = time
        _this.played = time / $audio.duration
      }
      $audio.onended = function() {
        _this.nextSong()
        $audio.play()
      }
      $audio.onerror = () => {
        _this.isPaused = true
        _this.isError = true
        Message.error('歌曲《' + _this.curSong.title + '》加载出错了')
      }
      $audio.onloadedmetadata = () => {
        _this.duration = $audio.duration
      }
      $audio.ondurationchange = () => {
        _this.duration = $audio.duration
      }
      $audio.onprogress = () => {
        const len = $audio.buffered.length
        if (len <= 0) {
          return
        }
        const time = $audio.buffered.end(len - 1)
        _this.preload = time / $audio.duration
      }
      if ('mediaSession' in navigator) {
        navigator.mediaSession.setActionHandler('previoustrack', () => {
          this.prevSong()
        })
        navigator.mediaSession.setActionHandler('nexttrack', () => {
          this.nextSong()
        })
      }
    },
    getPlayList(listId) {
      this.$http.jsonp('https://api.asilu.com/cloud-music/163', {
        params: {
          type: 'playlist',
          id: listId
        }
      }).then((response) => {
        const list = response.body.list
        this.playList = list
        if (list.length > 0 && !this.curSong.id) {
          this.changeSong(list[0])
        }
      })
    },
    getLyric(id) {
      this.sourceLyric = ''
      this.searching = true
      fetch('https://api.asilu.com/163music/?type=songlrc&lrc=lrc&id=' + id).then((response) => {
        return response.text()
      }).then((text) => {
        if (text) {
          this.sourceLyric = text
        }
      }).finally(() => {
        this.searching = false
      })
    },
    updateTime(val) {
      this.played = val
      if (this.$audio) {
        this.$audio.currentTime = val * this.$audio.duration
      }
    },
    toggleShow() {
      const _this = this
      function hide() {
        _this.isShow = false
        document.removeEventListener('click', hide)
      }
      if (this.isShow) {
        hide()
      } else {
        this.isShow = true
        setTimeout(() => {
          document.addEventListener('click', hide)
        }, 0)
      }
    }
  }
}
</script>

<style scoped lang="less">
  @font-color: #f9f9f9;
  .audio-player-warp{
    width: 100%;
    height: 100%;
    position: relative;
    background-color: #d9dce0;
    background-position: center;
    background-size: cover;
    background-repeat: no-repeat;
    overflow: hidden;
  }
  .audio-bg{
    position: absolute;
    width: 100%;
    height: 100%;
    left: 0;
    top: 0;
    bottom: 0;
    right: 0;
    background-color: rgba(0, 0, 0, 0.4);
  }
  .audio-player-control{
    position: relative;
  }
  .player-control-warp{
    text-align: center;
    padding: 15px 0;
    position: relative;
  }
  .player-control-warp .iconfont{
    font-size: 30px;
    display: inline-block;
    width: 40px;
    line-height: 40px;
    vertical-align: middle;
    text-align: center;
    color: @font-color;
  }
  .player-control-warp .toggle-play{
    font-size: 35px;
  }
  .player-control-warp .icon-menu{
    position: absolute;
    right: 15px;
    top: 15px;
  }
  .curTime-text{
    float: left;
    display: block;
    width: 50px;
    text-align: center;
    line-height: 20px;
    font-size: 12px;
    color: @font-color;
  }
  .duration-text{
    float: right;
    display: block;
    width: 50px;
    text-align: center;
    line-height: 20px;
    font-size: 12px;
    color: @font-color;
  }
  .audio-duration-warp{
    margin: 0 50px;
    height: 4px;
    padding: 8px 0;
  }
  .audio-header{
    height: 30px;
    line-height: 30px;
    text-align: center;
    font-size: 14px;
    color: @font-color;
    position: relative;
  }
  .audio-lyric-warp{
    width: 100%;
    height: calc(100% - 120px);
    position: relative;
  }
  .audio-lyric-warp/deep/ .ui-lyric-item{
    font-size: 14px;
    line-height: 28px;
    color: @font-color;
  }
  .audio-lyric-warp/deep/ .ui-lyric-item.active{
    color: #ffc63c;
  }
  .audio-list-warp{
    position: absolute;
    left: 0;
    bottom: 0;
    right: 0;
    transform: translateY(0);
    transition: all .2s;
    opacity: 1;
  }
  .audio-list-warp.list-hide{
    transform: translateY(100%);
    opacity: 0.3;
  }
  .audio-list-header{
    line-height: 36px;
    height: 36px;
    font-size: 14px;
    color: #3a3c3e;
    padding: 0 15px;
    background-color: #ffffff;
    border-radius: 4px 4px 0 0;
    border-bottom:1px solid #f2f2f2 ;
    margin: 0;
  }
  .audio-list-container{
    list-style: none;
    background-color: #ffffff;
    max-height: 260px;
    padding: 0;
    margin: 0;
    overflow-y: auto;
  }
  .audio-list-container li{
    line-height: 30px;
    height: 30px;
    padding: 0 15px;
    font-size: 14px;
    color: #666666;
    overflow: hidden;
    text-overflow: ellipsis;
    word-wrap: normal;
  }
  .audio-list-container li:nth-child(odd){
    background-color: #f7f7f7;
  }
</style>
